#ifndef BASE_CTTCPTASK_H_
#define BASE_CTTCPTASK_H_
#include "Zebra.h"
#include "ct_noncopyable.h"
#include "ctSocket.h"
#include "ctLog.h"
#include "ct_log_macro.h"

class ctTCPTaskPool;
class ctTCPTask : 
        public ctProcessor,
        private ctNoncopyable
{
        public:
                enum TerminateMethod
                {
                        terminate_no,		//not terminate
                        terminate_active,	//client close
                        terminate_passive,	//server close
                };

                ctTCPTask( ctTCPTaskPool *pool,
                                const int sock,
                                const struct sockaddr_in *addr = NULL,
                                const bool compress = false,
                                const bool checkSignal = true)
                        :mSocket(sock,addr,compress), pool(pool), _checkSignal(checkSignal), tick(false), _tick_timer(60)
                {
                        terminate = terminate_no;
                        terminate_wait = false; 
                        fdsradd = false; 
                        buffered = false;
                        state = notuse;
                        check_count =0;
                }

                virtual ~ctTCPTask() 
                {
                        CT_TRACE("%s. id:%u", __PRETTY_FUNCTION__, sock());
                }

                void addEpollFD(int kdpfd,__uint32_t events, void* ptr)
                {
                        mSocket.addEpoll(kdpfd,events, ptr);
                }
                void delEpollFD(int kdpfd,__uint32_t events)
                {
                        mSocket.delEpoll(kdpfd, events);
                }
                //check if verify timeout
                bool checkVerifyTimeout(const ctRTime &ct,const QWORD interval = 5000) const
                {
                        return (lifeTime.elapse(ct) > interval);
                }

                bool isFdsrAdd()
                {
                        return fdsradd;
                }
                bool fdsrAdd()
                {
                        fdsradd=true;
                        return fdsradd;
                }
                virtual int verifyConn()
                {
                        return 1;
                }

                virtual int waitSync()
                {
                        return 1;
                }
                //is recycel succesful? when successful, need del related info
                virtual int recycleConn()
                {
                        return 1;
                }

                //when a conncet task verify sucessful, need add to extern container.
                virtual void addToContainer() {}

                //when connect closed, need remove from extern container
                virtual void removeFromContainer() {}

                //add connect task to extern container. Make sure the connect object is unique.
                virtual bool uniqueAdd()
                {
                        return true;
                }

                //remove connect task from extern container. Make sure the connect is unique.
                virtual bool uniqueRemove()
                {
                        return true;
                }

                //set flag of unique verify passed
                void setUnique()
                {
                        uniqueVerified = true;
                }

                //is the task unique
                bool isUnique() const
                {
                        return uniqueVerified;
                }

                //is be Set terminate_wait status by other thread
                bool isTerminateWait()
                {
                        return terminate_wait; 
                }

                void TerminateWait()
                {
                        CT_TRACE("%s:socket(%u)", __PRETTY_FUNCTION__, mSocket.Sock());
                        terminate_wait=true; 
                }

                bool isTerminate() const
                {
                        return terminate_no != terminate;
                }

                //close client connection actively
                //method: close method
                virtual void Terminate(const TerminateMethod method = terminate_passive)
                {
                        terminate = method;
                        clearTick();
                }

                int32_t getTerminateState() const {
                    return terminate;
                }

                virtual bool sendCmd(const void *,int);
                bool sendCmdNoPack(const void *,int);
                virtual bool ListeningRecv(bool);
                virtual bool ListeningSend();

                //connection task status
                enum ctTCPTask_State
                {
                        notuse	=  0, //connection close
                        verify	=  1, //connection verify status
                        sync	=  2, //wait verify info from other server
                        okay	=  3, //verify ok. main loop
                        recycle	=  4  //connection recycle state.
                };

                const ctTCPTask_State getState() const
                {
                        return state;
                }

                void setState(const ctTCPTask_State state)
                {
                        this->state = state;
                }

                void getNextState();
                void resetState();

                const char *getStateString(const ctTCPTask_State state) const
                {
                        const char *retval = NULL;

                        switch(state)
                        {
                                case notuse:
                                        retval = "notuse";
                                        break;
                                case verify:
                                        retval = "verify";
                                        break;
                                case sync:
                                        retval = "sync";
                                        break;
                                case okay:
                                        retval = "okay";
                                        break;
                                case recycle:
                                        retval = "recycle";
                                        break;
                                default:
                                        retval = "none";
                                        break;
                        }

                        return retval;
                }

                const char *getIP() const
                {
                        return mSocket.getIP();
                }
                const DWORD getAddr() const
                {
                        return mSocket.getAddr();
                }

                const WORD getPort()
                {
                        return mSocket.getPort();
                }

                const bool ifCheckSignal() const
                {
                        return _checkSignal;
                }

                bool checkInterval(const ctRTime &ct)
                {
                        return _tick_timer(ct);
                }

                bool checkTick() const
                {
                        return tick;
                }

                void clearTick()
                {
                        tick = false;
                }

                void setTick()
                {
                        tick = true;
                }
                ctTCPTaskPool *getPool()
                {
                        return pool; 
                }

                void checkSignal(const ctRTime &ct);
                int sock(){return mSocket.Sock();}

                void setLostPkg(bool b) { mSocket.setLostPkg(b); }

        protected:
                bool buffered;			//send cmd need bufferd
                ctSocket mSocket;
                ctTCPTask_State state;		//connection state

        private:
                ctTCPTaskPool *pool;		//task in which pool
                TerminateMethod terminate;	//is terminated
                bool terminate_wait;		//other thread set wait state, and be set close state by pool thread
                bool fdsradd;			//read event add flag
                ctRTime lifeTime;		//connection task create time

                bool uniqueVerified;
                const bool _checkSignal;
                bool tick;
                Timer _tick_timer;
                BYTE check_count;

};

#endif //BASE_CTTCPTASK_H_
